package cn.zwx.infra.svc.service.impl.sms;

import cn.hutool.core.collection.CollUtil;
import cn.zwx.base.exception.BizWrapException;
import cn.zwx.base.projo.SortablePageParam;
import cn.zwx.base.projo.SortingField;
import cn.zwx.base.utils.PageUtil;
import cn.zwx.common.mybatis.query.LambdaQueryWrapperX;
import cn.zwx.infra.svc.domain.entity.SmsChannelEntity;
import cn.zwx.infra.svc.domain.enums.InfraRespCodeEnum;
import cn.zwx.infra.svc.domain.wrap.ExceptionWrap;
import cn.zwx.infra.svc.domain.wrap.SmsChannelWrap;
import cn.zwx.infra.svc.dto.SmsChannelPageDTO;
import cn.zwx.infra.svc.dto.SmsChannelSaveDTO;
import cn.zwx.infra.svc.dto.SmsChannelUpdateDTO;
import cn.zwx.infra.svc.mapper.InfraSmsChannelMapper;
import cn.zwx.infra.svc.service.sms.SmsChannelService;
import cn.zwx.infra.svc.vo.SmsChannelSimpleVO;
import cn.zwx.infra.svc.vo.SmsChannelVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangwenxue
 */
@Service
public class SmsChannelServiceImpl  implements SmsChannelService {

    @Resource
    private InfraSmsChannelMapper mapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSmsChannel(SmsChannelSaveDTO dto) {
        // 1.builder entity
        final SmsChannelEntity smsChannel = SmsChannelWrap.warp(dto);
        // 2.sava to db
        mapper.insert(smsChannel);
        // 3.return obj
        return smsChannel.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateSmsChannel(SmsChannelUpdateDTO dto) throws BizWrapException {
        // 1.check exists ...
        this.validSmsChannelExists(dto.getId());
        // 2.builder entity
        SmsChannelEntity smsChannel = SmsChannelWrap.warp2(dto);
        // 3.update
        final int updateById = mapper.updateById(smsChannel);
        // 4.return
        return updateById == 1;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteSmsChannel(Long id) throws BizWrapException {
        // 1.check exists ...
        this.validSmsChannelExists(id);
        // 2.delete
        final SmsChannelEntity smsChannel = new SmsChannelEntity();
        smsChannel.setId(id);
        smsChannel.setDeleted(1);
        final int updateById = mapper.updateById(smsChannel);
        // 3.return
        return updateById == 1 ;
    }

    @Override
    public SmsChannelVO getSmsChannel(Long id) {
        // 1.query
        final LambdaQueryWrapperX<SmsChannelEntity> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eq(SmsChannelEntity::getId,id);
        wrapperX.eq(SmsChannelEntity::getDeleted,0);
        final SmsChannelEntity smsChannel = mapper.selectOne(wrapperX);
        // 2.return
        if (smsChannel == null) {
          return null;
        }
        return SmsChannelWrap.warp3(smsChannel);
    }

    @Override
    public PageUtil<SmsChannelVO> getSmsChannelPage(SmsChannelPageDTO dto) {
        // 1.query
        // 1.1 page
        final SortablePageParam pageParam = new SortablePageParam();
        pageParam.setPageNo(dto.getPageNo());
        pageParam.setPageSize(dto.getPageSize());
        List<SortingField> sortingFields = new ArrayList<>();
        sortingFields.add(new SortingField("create_time",SortingField.ORDER_ASC));
        pageParam.setSortingFields(sortingFields);
        // 1.2 wrapper
        final LambdaQueryWrapperX<SmsChannelEntity> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eqIfPresent(SmsChannelEntity::getStatus,dto.getStatus());
        wrapperX.likeIfPresent(SmsChannelEntity::getStatus,dto.getSignature());
        wrapperX.betweenIfPresent(SmsChannelEntity::getCreateTime,dto.getStartTime(),dto.getEndTime());
        // 1.3 select page
        final PageUtil<SmsChannelEntity> selectPage = mapper.selectPage(pageParam, wrapperX);
        // 2.return
        final PageUtil<SmsChannelVO> voPageUtil = new PageUtil<>(dto.getPageSize(), dto.getPageNo(), selectPage.getTotal(), new ArrayList<>());
        final List<SmsChannelEntity> records = selectPage.getRecords();
        if (CollUtil.isEmpty(records)){
            return voPageUtil;
        }
        final List<SmsChannelVO> dataList = new ArrayList<>(records.size());
        records.forEach(t->
                dataList.add(SmsChannelWrap.warp3(t)));

        return new PageUtil<>(dto.getPageSize(), dto.getPageNo(), dataList.size(), dataList);
    }

    @Override
    public List<SmsChannelSimpleVO> getSimpleSmsChannelList() {
        // 1.query
        final LambdaQueryWrapperX<SmsChannelEntity> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eq(SmsChannelEntity::getDeleted,0);
        final List<SmsChannelEntity> selectList = mapper.selectList(wrapperX);
        if (CollUtil.isEmpty(selectList)){
            return new ArrayList<>();
        }
        // 2.returnList
        List<SmsChannelSimpleVO> returnList = new ArrayList<>(selectList.size());
        selectList.forEach(t->{
            final SmsChannelSimpleVO simpleVO = new SmsChannelSimpleVO();
            simpleVO.setCode(t.getChannelCode());
            simpleVO.setId(t.getId());
            simpleVO.setSignature(t.getSignature());
            returnList.add(simpleVO);
        });
        return returnList;
    }

    private void validSmsChannelExists(Long id) throws BizWrapException {
        final SmsChannelEntity channelEntity = mapper.selectById(id);
        if ( channelEntity == null){
            throw ExceptionWrap.wrap(InfraRespCodeEnum.SMS_CHANNEL_NOT_EXISTS_ERROR);
        }
    }
}
